import time
from typing import Tuple

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.remote.webelement import WebElement

Loc = Tuple[str, str]

class BasePage:
    def __init__(self, *, driver: WebDriver, url: str, wait_time: int=10):
        self.driver: WebDriver = driver
        self.url: str = url
        self.actions = ActionChains(driver)
        self.wait_time: int = wait_time

    def get_cookies(self) -> dict:
        cookies = self.driver.get_cookies()
        cookies_dict = {c['name']: c['value'] for c in cookies}
        return cookies_dict

    def open(self):
        """打开页面"""
        if self.url:
            self.driver.get(self.url)
            self.driver.maximize_window()

    def on_page(self, page_title: str) -> bool:
        """根据页面 title 判断是否打开了这个页面"""
        return page_title in self.driver.title

    def find_element(self, loc: Loc) -> WebElement:
        """loc 是元组, 例如 By.ID, "some_id"  """
        try:
            return WebDriverWait(self.driver, self.wait_time).until(EC.presence_of_element_located(loc))
        except:
            raise

    # Fixme: return type?
    def find_elements(self, loc: Loc):
        try:
            return WebDriverWait(self.driver, self.wait_time).until(EC.presence_of_all_elements_located(loc))
        except:
            raise

    def input_text(self, loc: Loc, text: str, clear: bool=True):
        """input 输入操作"""
        ele_input: WebElement = self.find_element(loc)
        try:
            if clear:
                ele_input.clear()
            ele_input.send_keys(text)
        except:
            raise

    def get_text(self, loc: Loc) -> str:
        ele = self.find_element(loc)
        return ele.text

    def get_element_attribute(self, loc: Loc, attribute: str) -> str:
        """获取元素属性值"""
        ele = self.find_element(loc)
        try:
            ele_attribute: str = ele.get_attribute(attribute)
            return ele_attribute
        except:
            raise

    def hover(self, loc: Loc):
        ele: WebElement = self.find_element(loc)
        ActionChains(self.driver).move_to_element(ele).perform()

    def click(self, loc: Loc):
        ele = self.find_element(loc)
        try:
            ele.click()
        except:
            pass

    def try_alert(self, wait_accept_time: int=1):
        try:
            # Fixme: 这里的 until 会返回 alert 实例吗? 是的话就不需要 switch 了
            WebDriverWait(self.driver, self.wait_time).until(EC.alert_is_present(), "等待 alert 超时")
            alert = self.driver.switch_to.alert
            time.sleep(wait_accept_time)
            alert.accept()
        except:
            raise

